const { ethers } = require("hardhat");
const fs = require("fs");
const path = require("path");

async function main() {
    console.log("🚀 开始部署代理合约项目（健壮版本）...\n");

    // 获取部署者账户
    const [deployer] = await ethers.getSigners();
    console.log(`📝 部署者地址: ${deployer.address}`);

    // 部署逻辑合约 V1
    console.log("\n📦 部署 LogicContractV1...");
    const LogicContractV1 = await ethers.getContractFactory("LogicContractV1");
    const logicV1 = await LogicContractV1.deploy();
    await logicV1.waitForDeployment();
    const logicV1Address = await logicV1.getAddress();
    console.log(`✅ LogicContractV1 部署成功: ${logicV1Address}`);

    // 验证逻辑合约 V1 有代码
    const logicV1Code = await ethers.provider.getCode(logicV1Address);
    console.log(`🔍 LogicContractV1 代码长度: ${logicV1Code.length}`);
    if (logicV1Code === '0x') {
        throw new Error("LogicContractV1 没有代码，部署失败");
    }

    // 部署代理合约
    console.log("\n📦 部署 ProxyContract...");
    const ProxyContract = await ethers.getContractFactory("ProxyContract");
    const proxy = await ProxyContract.deploy(logicV1Address);
    await proxy.waitForDeployment();
    const proxyAddress = await proxy.getAddress();
    console.log(`✅ ProxyContract 部署成功: ${proxyAddress}`);

    // 验证代理合约有代码
    const proxyCode = await ethers.provider.getCode(proxyAddress);
    console.log(`🔍 ProxyContract 代码长度: ${proxyCode.length}`);
    if (proxyCode === '0x') {
        throw new Error("ProxyContract 没有代码，部署失败");
    }

    // 将代理合约附加 LogicContractV1 的 ABI
    const proxyAsV1 = await ethers.getContractAt("LogicContractV1", proxyAddress);

    // 初始化代理合约
    console.log("\n🔧 初始化代理合约...");
    try {
        const initTx = await proxyAsV1.initialize();
        const receipt = await initTx.wait();
        console.log(`✅ 代理合约初始化成功，区块: ${receipt.blockNumber}`);
    } catch (error) {
        console.log("⚠️ 初始化可能已经完成:", error.message);
    }

    // 测试 V1 功能
    console.log("\n🧪 测试 V1 功能...");

    // 设置数字
    console.log("设置 number = 100...");
    const setTx = await proxyAsV1.setNumber(100);
    await setTx.wait();

    // 读取数字
    const number = await proxyAsV1.getNumber();
    console.log(`✅ 读取 number = ${number}`);

    if (number !== 100n) {
        throw new Error("设置数字测试失败");
    }

    // 增加数字
    console.log("增加 number + 50...");
    const increaseTx = await proxyAsV1.increaseNumber(50);
    await increaseTx.wait();
    const newNumber = await proxyAsV1.getNumber();
    console.log(`✅ 增加后 number = ${newNumber}`);

    if (newNumber !== 150n) {
        throw new Error("增加数字测试失败");
    }

    // 获取版本
    const version = await proxyAsV1.version();
    console.log(`✅ 当前版本: ${version}`);

    // 验证代理合约的存储
    console.log("\n🔍 验证代理合约存储...");
    const implementationSlot = await ethers.provider.getStorage(proxyAddress, 0);
    console.log(`📋 Slot 0 (implementation): ${implementationSlot}`);

    const numberSlot = await ethers.provider.getStorage(proxyAddress, 1);
    console.log(`📋 Slot 1 (number): ${numberSlot}`);

    const adminSlot = await ethers.provider.getStorage(proxyAddress, 2);
    console.log(`📋 Slot 2 (admin): ${adminSlot}`);

    // 保存部署信息
    const deploymentInfo = {
        logicV1: logicV1Address,
        proxy: proxyAddress,
        deployer: deployer.address,
        network: "hardhat",
        deployedAt: new Date().toISOString()
    };

    const deploymentFile = path.join(__dirname, 'deployment.json');
    fs.writeFileSync(deploymentFile, JSON.stringify(deploymentInfo, null, 2));

    console.log("\n📋 部署信息:");
    console.log(JSON.stringify(deploymentInfo, null, 2));
    console.log("\n🎉 部署完成！所有验证通过！");

    return deploymentInfo;
}

main()
    .then((result) => {
        console.log(`\n💡 代理合约地址: ${result.proxy}`);
        console.log(`💡 逻辑合约 V1 地址: ${result.logicV1}`);
        process.exit(0);
    })
    .catch((error) => {
        console.error("❌ 部署失败:", error);
        process.exit(1);
    });